/**
 * Created by 居胜 on 2016/7/21.
 *
 * 通过原生js, 以及Tween算法， 实现时间版的运动函数
 * @params obj 运动的对象
 * @params json 那个属性需要运动，json格式
 * @params type 运动的形式
 * @params times  在多长时间内完成运动
 * @params fn  运动完成后的回调函数
 */
function move(obj, json, type, times, fn) {

    clearInterval( obj.timer );

    //初始值
    var startValue = {};
    for(var attr in json){
        startValue[attr] = parseFloat(getStyle(obj, attr));
    }

    //开始时间
    var startTime = (new Date()).getTime();

    obj.timer = setInterval(function () {

        //现在的时间
        var endTime = (new Date()).getTime();

        //这种转换为 0 ~ times 的思想可以掌握
        var currentTime = times - Math.max(0, (startTime - endTime + times));

        for(var attr in json){
            var change = Tween[type](currentTime, startValue[attr], (json[attr] - startValue[attr]), times);

            obj.style[attr] = change + 'px';
        }

        //如果时间到达，清除定时器，运动结束
        if(currentTime == times){
            clearInterval(obj.timer);
            if(fn){
                fn.call(obj);
            }
        }

    }, 13)
}

//获取CSS样式值
function getStyle(obj, attr) {

    //IE
    if(obj.currentStyle){
        return obj.currentStyle[attr];

    }else if(window.getComputedStyle){
        return window.getComputedStyle(obj, false)[attr];
    }
}

//Tween 算法, 只选取了部分
var Tween = {
    Linear: function(t,b,c,d){ return c*t/d + b; },
    Quad: {
        easeIn: function(t,b,c,d){
            return c*(t/=d)*t + b;
        },
        easeOut: function(t,b,c,d){
            return -c *(t/=d)*(t-2) + b;
        },
        easeInOut: function(t,b,c,d){
            if ((t/=d/2) < 1) return c/2*t*t + b;
            return -c/2 * ((--t)*(t-2) - 1) + b;
        }
    },
    Back: {
        easeIn: function(t,b,c,d,s){
            if (s == undefined) s = 1.70158;
            return c*(t/=d)*t*((s+1)*t - s) + b;
        },
        easeOut: function(t,b,c,d,s){
            if (s == undefined) s = 1.70158;
            return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
        },
        easeInOut: function(t,b,c,d,s){
            if (s == undefined) s = 1.70158;
            if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
            return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
        }
    },
    Bounce: {
        easeIn: function(t,b,c,d){
            return c - Tween.Bounce.easeOut(d-t, 0, c, d) + b;
        },
        easeOut: function(t,b,c,d){
            if ((t/=d) < (1/2.75)) {
                return c*(7.5625*t*t) + b;
            } else if (t < (2/2.75)) {
                return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
            } else if (t < (2.5/2.75)) {
                return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
            } else {
                return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
            }
        },
        easeInOut: function(t,b,c,d){
            if (t < d/2) return Tween.Bounce.easeIn(t*2, 0, c, d) * .5 + b;
            else return Tween.Bounce.easeOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
        }
    }
};